import { useEffect, useState, useMemo, useCallback } from 'react';
import { Tabs, List, Empty, Input, Typography } from 'antd';
import Cookies from 'js-cookie';
import DataTable from './components/DataTable';
import DataTree, { updateTreeData } from './components/DataTree';
import SearchBar from './components/SearchBar';
import service from './service';
import {
  calcTableScrollHeight,
  decorateKey,
  decorateRowKey,
  getMemberIconByKey,
  getLowercase,
} from './utils';
import { DEFAULT_PAGE_SIZE, PREFIX, TabKey } from './utils/consts';
import { InbizIcon } from '@inbiz/utils';
import { renderCellText } from './utils/tableUtil';
import { TextWidget, getMessage } from '@inbiz/react';
const { Text } = Typography;

export default function UserTab(props: any) {
  const {
    selectedRowKeys,
    multiple,
    setSelected,
    tabKey,
    height,
    topDepartmentIds,
    isUnique,
    forbiddenItems,
    tab,
    collectivization,
    configEvents,
    departmentFilteringRules,
  } = props;

  const { ifUserGroupSelected, userGroupFilterRule, userGroupSelector, userGroups } = tab;

  const [departmentTreeData, setDepartmentTreeData] = useState<any[]>([]);
  const [selectedKeys, _selectedKeys] = useState<string[]>([]);
  const [expandedKeys, _expandedKeys] = useState<string[]>([]);
  const [pageNum, _pageNum] = useState(1);
  const [pageSize, _pageSize] = useState(props.pageSize || DEFAULT_PAGE_SIZE);
  const [groupPageNum, setGroupPageNum] = useState(1);
  const [groupPageSize, setGroupPageSize] = useState(props.pageSize || DEFAULT_PAGE_SIZE);
  const [isChild, _isChild] = useState(true);
  const [total, _total] = useState(0);
  const [groupTotal, setGroupTotal] = useState(0);
  const [departmentSearchValue, _departmentSearchValue] = useState('');
  const [userGroupSearchValue, setUserGroupSearchValue] = useState('');
  const [departmentData, _departmentData] = useState<any[]>([]);
  const [userGroupData, setUserGroupData] = useState<any[]>([]);
  const [currentTab, setCurrentTab] = useState('department');
  const [currentUserGroup, setCurrentUserGroup] = useState('');
  const [userGroupUserList, setUserGroupUserList] = useState<any[]>([]);
  const [userTopDeptId, setUserTopDeptId] = useState();
  const [selectedDeptId, setSelectedDeptId] = useState(userTopDeptId);

  const {
    getTopDepartmentList,
    getSubDepartmentList,
    getUserList,
    getUserGroupList,
    getUserGroupUserList,
    getGroupInfoByIds,
  } = service;

  const _getTopDepartmentList = useCallback(async (params: object) => {
    const newParams = (await configEvents.current?.onGetTopDepartmentsParams?.(params)) || params;
    const data = await (configEvents.current?.onGetTopDepartmentsRequest || getTopDepartmentList)(newParams as any);
    return await configEvents.current?.onGetTopDepartsmentData?.(data) || data;
  }, []);

  const _getSubDepartmentList = useCallback(async (params: object) => {
    const newParams = (await configEvents.current?.onGetSubDepartmentsParams?.(params)) || params;
    const data = await (configEvents.current?.onGetSubDepartmentsRequest || getSubDepartmentList)(newParams as any);
    return await configEvents.current?.onGetSubDepartmentsData?.(data) || data;
  }, []);

  const _getUserList = useCallback(async (params: object) => {
    const newParams = (await configEvents.current?.onGetDepartmentUsersParams?.(params)) || params;
    const data = await (configEvents.current?.onGetDepartmentUsersRequest || getUserList)(newParams as any);
    return await configEvents.current?.onGetDepartmentUsersData?.(data) || data;
  }, []);

  const _getUserGroupList = useCallback(async (params: object) => {
    const newParams = (await configEvents.current?.onGetGroupsParams?.(params)) || params;
    const data = await (configEvents.current?.onGetGroupsRequest || getUserGroupList)(newParams as any);
    return await configEvents.current?.onGetGroupsData?.(data) || data;
  }, []);

  const _getUserGroupUserList = useCallback(async (params: object) => {
    const newParams = (await configEvents.current?.onGetGroupUsersParams?.(params)) || params;
    const data = await (configEvents.current?.onGetGroupUsersRequest || getUserGroupUserList)(newParams as any);
    return await configEvents.current?.onGetGroupUsersData?.(data) || data;
  }, []);

  const isGroup = useMemo(() => {
    return currentTab == 'userGroup' || (ifUserGroupSelected && tab?.ifUserDepartmentSelected === false);
  }, [currentTab, tab]);

  const departmentDecorateData = decorateKey(tabKey, (data) => {
    return {
      icon: getMemberIconByKey(TabKey.Department, forbiddenItems.includes(data.id) ? true : false),
    };
  });

  const userGroupDecorateData = decorateKey(tabKey, (data) => {
    return {
      icon: getMemberIconByKey(TabKey.Group, forbiddenItems.includes(data.id) ? true : false),
    };
  });

  const rowKey = decorateRowKey(tabKey);

  const getDeptId = (selKeys?: string[]) => {
    let keys = selKeys || selectedKeys;
    if (keys.length) {
      let key = keys[0];
      const [tabKey, deptId] = key.split('-');
      if (deptId) {
        return Number(deptId);
      }
    }
  };

  const onDepartmentSearch = (value: string, checked: boolean) => {
    _departmentSearchValue(value);
    _isChild(checked);
    _getUserList({
      departmentId: getDeptId() as number,
      searchContent: value,
      isChild: checked,
      pageNum: 1,
      pageSize: pageSize,
    })
      .then((res) => {
        if (res?.Info) {
          _departmentData(
            (getLowercase(res?.Info, tabKey) || [])
              .map(departmentDecorateData)
              ?.map((item: any) => {
                return {
                  ...item,
                  usertype: 'department',
                  departmentid: selectedDeptId,
                };
              }),
          );
          _pageNum(1);
          _total(res.Total);
        }
      });
  };

  const onUserGroupSearch = () => {
    let _groupId = userGroupData?.find((item: any) => item?.key == currentUserGroup)?.id;
    let _groupName = userGroupData?.find((item: any) => item?.key == currentUserGroup)?.name;
    let _params = {
      groupId: _groupId,
      userNme: userGroupSearchValue,
      page: 1,
      rows: groupPageSize,
    };
    _getUserGroupUserList(_params).then((res: any) => {
      if (res?.rows && res?.rows?.length > 0) {
        setUserGroupUserList(
          getLowercase(res?.rows, tabKey)?.map((item: any) => {
            return {
              ...item,
              deptpathname: item?.maindepartmentname || '',
              useremail: item?.email || '',
              usertype: 'userGroup',
              groupname: _groupName,
              groupid: _groupId,
              memberarea: 0,
              userloginname: item?.account,
            };
          }),
        );
      } else {
        setUserGroupUserList([]);
      }
      setGroupPageNum(1);
      setGroupTotal(res?.total);
    });
  };

  const onPagination = (pagination: { current: number; pageSize: number }) => {
    if (isGroup) {
      let _groupId = userGroupData?.find((item: any) => item?.key == currentUserGroup)?.id;
      let _groupName = userGroupData?.find((item: any) => item?.key == currentUserGroup)?.name;
      let _params = {
        groupId: _groupId,
        userNme: userGroupSearchValue,
        page: pagination.current,
        rows: pagination.pageSize,
      };
      _getUserGroupUserList(_params).then((res: any) => {
        if (res?.rows && res?.rows?.length > 0) {
          setUserGroupUserList(
            getLowercase(res?.rows, tabKey)?.map((item: any) => {
              return {
                ...item,
                deptpathname: item?.maindepartmentname || '',
                useremail: item?.email || '',
                usertype: 'userGroup',
                groupname: _groupName,
                groupid: _groupId,
                memberarea: 0,
                userloginname: item?.account,
              };
            }),
          );
        } else {
          setUserGroupUserList([]);
        }
        setGroupTotal(res?.total);
        setGroupPageNum(pagination.current);
        setGroupPageSize(pagination.pageSize);
      });
    } else {
      _getUserList({
        departmentId: getDeptId() as number,
        searchContent: departmentSearchValue,
        isChild: isChild,
        pageNum: pagination.current,
        pageSize: pagination.pageSize,
      })
        .then((res) => {
          if (res?.Info) {
            _departmentData(
              (getLowercase(res?.Info, tabKey) || [])
                .map(departmentDecorateData)
                ?.map((item: any) => {
                  return {
                    ...item,
                    usertype: 'department',
                    departmentid: selectedDeptId,
                  };
                }),
            );
            _total(res.Total);
            _pageNum(pagination.current);
            _pageSize(pagination.pageSize);
          }
        });
    }
  };

  const onSelect = (keys: any, e: { node: any }) => {
    if (keys.length) {
      _selectedKeys(keys);
      const deptId = getDeptId(keys);
      if (deptId) {
        _getUserList({
          departmentId: deptId,
          searchContent: departmentSearchValue,
          isChild: isChild,
          pageNum: 1,
          pageSize: pageSize,
        })
          .then((res) => {
            if (res?.Info) {
              _departmentData(
                (getLowercase(res?.Info, tabKey) || [])
                  .map(departmentDecorateData)
                  ?.map((item: any) => {
                    return {
                      ...item,
                      usertype: 'department',
                      departmentid: e?.node?.id,
                    };
                  }),
              );
              _pageNum(1);
              _total(res.Total);
            }
          });
      }
    }
  };

  useEffect(() => {
    if (tab?.ifUserDepartmentSelected !== false) {
      if (departmentFilteringRules != 'exceptSelected' || departmentFilteringRules == 'exceptSelected' && topDepartmentIds?.length == 1 && topDepartmentIds?.[0] == 1 || departmentFilteringRules == 'exceptSelected' && topDepartmentIds?.length == 0 || collectivization) {
        _getTopDepartmentList({
          departmentIds: collectivization
            ? Cookies.get('orgIdentityId')
              ? [Cookies.get('orgIdentityId')]
              : [1]
            : departmentFilteringRules == 'exceptSelected' && topDepartmentIds?.length == 1 && topDepartmentIds?.[0] == 1 ? [] : departmentFilteringRules != 'exceptSelected' && topDepartmentIds?.length == 0 ? [1] : departmentFilteringRules == 'exceptSelected' && topDepartmentIds?.length == 0 ? [1] : topDepartmentIds,
        })
          .then((res) => {
            if (Array.isArray(res) && res.length) {
              if ((collectivization
                ? Cookies.get('orgIdentityId')
                  ? [Cookies.get('orgIdentityId')]
                  : [1]
                : topDepartmentIds || [1])?.join('') == '1') {
                setUserTopDeptId(res?.[0]?.Id)
                setSelectedDeptId(res?.[0]?.Id);
              } else {
                _getTopDepartmentList({
                  departmentIds: [1],
                }).then((res1) => {
                  if (Array.isArray(res1) && res1.length) {
                    setUserTopDeptId(res1?.[0]?.Id)
                    setSelectedDeptId(res1?.[0]?.Id);
                  }
                })
              }
              const keys = [departmentDecorateData(getLowercase(res, tabKey)[0]).key];
              _selectedKeys(keys);
              _expandedKeys(keys);
              setDepartmentTreeData(getLowercase(res, tabKey).map(departmentDecorateData));
              _getUserList({
                departmentId: getDeptId(keys) as number,
                searchContent: '',
                isChild: true,
                pageNum: 1,
                pageSize: pageSize,
              })
                .then((res2) => {
                  if (res2?.Info) {
                    _departmentData(
                      (getLowercase(res2?.Info, tabKey) || [])
                        .map(departmentDecorateData)
                        ?.map((item: any) => {
                          return {
                            ...item,
                            usertype: 'department',
                            departmentid: res?.[0]?.Id,
                          };
                        }),
                    );
                    _pageNum(1);
                    _total(res2.Total);
                  }
                });
            }
          });
      } else {
        _getSubDepartmentList({
          departmentId: 1,
          banDeptIds: topDepartmentIds,
        }).then((res) => {
          if (Array.isArray(res) && res.length) {
            const keys = [departmentDecorateData(getLowercase(res, tabKey)[0]).key];
            _selectedKeys(keys);
            _expandedKeys(keys);
            setDepartmentTreeData(getLowercase(res, tabKey).map(departmentDecorateData));
            _getUserList({
              departmentId: getDeptId(keys) as number,
              searchContent: '',
              isChild: true,
              pageNum: 1,
              pageSize: pageSize,
            })
              .then((res2) => {
                if (res2?.Info) {
                  _departmentData(
                    (getLowercase(res2?.Info, tabKey) || [])
                      .map(departmentDecorateData)
                      ?.map((item: any) => {
                        return {
                          ...item,
                          usertype: 'department',
                          departmentid: res?.[0]?.Id,
                        };
                      }),
                  );
                  _pageNum(1);
                  _total(res2.Total);
                }
              });
          }
        })
      }
    }
  }, [tab?.ifUserDepartmentSelected]);

  const idsParam = useMemo(() => {
    if (collectivization) {
      return {}
    } else {
      if (!userGroups) {
        if (userGroupSelector?.type == 'all') {
          return {}
        } else {
          if (userGroupFilterRule == 'exceptSelected') {
            return {
              banGroupIds: userGroupSelector?.data?.map((item: { IdentityId: number; identityid: number; }) => item?.IdentityId || item?.identityid)?.join(','),
            }
          } else {
            return {
              pickGroupIds: userGroupSelector?.data?.map((item: { IdentityId: number; identityid: number; }) => item?.IdentityId || item?.identityid)?.join(','),
            }
          }
        }
      } else {
        if (userGroupFilterRule == 'exceptSelected') {
          return {
            banGroupIds: userGroups?.map((item: { IdentityId: number; identityid: number; }) => item?.IdentityId || item?.identityid)?.join(','),
          }
        } else {
          return {
            pickGroupIds: userGroups?.map((item: { IdentityId: number; identityid: number; }) => item?.IdentityId || item?.identityid)?.join(','),
          }
        }
      }
    }
  }, [userGroupFilterRule, userGroupSelector, userGroups, collectivization]);

  useEffect(() => {
    if (ifUserGroupSelected) {
      _getUserGroupList({
        pageIndex: 1,
        pageSize: 9999,
        ...idsParam,
      })
        .then((res) => {
          const data = JSON.parse(res.rows);
          let _userGroupData = (getLowercase(data, tabKey) || []).map(userGroupDecorateData);
          // ?.filter((item: any) => !filterItems?.includes(item?.identityid)),
          setUserGroupData(_userGroupData);
          setCurrentUserGroup(_userGroupData?.[0]?.key);
        });
    }
  }, [ifUserGroupSelected])

  useEffect(() => {
    if (currentUserGroup) {
      setUserGroupSearchValue('');
      let _groupId = userGroupData?.find((item: any) => item?.key == currentUserGroup)?.id;
      let _groupName = userGroupData?.find((item: any) => item?.key == currentUserGroup)?.name;
      let _params = {
        groupId: _groupId,
        userNme: '',
        page: 1,
        rows: groupPageSize,
      };
      _getUserGroupUserList(_params).then((res: any) => {
        if (res?.rows && res?.rows?.length > 0) {
          setUserGroupUserList(
            getLowercase(res?.rows, tabKey)?.map((item: any) => {
              return {
                ...item,
                deptpathname: item?.maindepartmentname || '',
                useremail: item?.email || '',
                usertype: 'userGroup',
                groupname: _groupName,
                groupid: _groupId,
                memberarea: 0,
                userloginname: item?.account,
              };
            }),
          );
        } else {
          setUserGroupUserList([]);
        }
        setGroupPageNum(1);
        setGroupTotal(res?.total);
      });
    }
  }, [currentUserGroup, userGroupData]);

  const departmentComponent = (
    <DataTree
      showIcon
      expandedKeys={expandedKeys}
      onExpand={(keys) => _expandedKeys(keys)}
      treeData={departmentTreeData}
      loadData={(e) => {
        return _getSubDepartmentList({
          departmentId: e.identityid,
          id: e.id,
        })
          .then((res) => {
            if (res) {
              setDepartmentTreeData((list) => {
                return updateTreeData(
                  list,
                  e.key,
                  getLowercase(res, tabKey).map(departmentDecorateData),
                );
              });
            }
          });
      }}
      multiple={false}
      selectedKeys={selectedKeys}
      onSelect={onSelect}
    />
  );

  const userGroupComponent = (
    <List
      className={`${PREFIX}-dataList`}
      style={{
        height: '100%',
      }}
      locale={{
        emptyText: (
          <Empty
            image={Empty.PRESENTED_IMAGE_SIMPLE}
            description={<TextWidget>MemberSelect.lang.noData</TextWidget>}
          />
        ),
      }}
      itemLayout="vertical"
      dataSource={userGroupData}
      rowKey={(row) => row.key}
      bordered={false}
      split={false}
      pagination={false}
      renderItem={(item: any, index) => {
        let _disabled = forbiddenItems.includes(item.id);
        return (
          <List.Item
            onClick={(e) => {
              if (_disabled) {
                return;
              }
              setCurrentUserGroup(item?.key);
            }}
            style={{ cursor: _disabled ? 'not-allowed' : 'pointer' }}
            className={currentUserGroup == item?.key ? 'memberItemSelected' : ''}
          >
            <List.Item.Meta
              avatar={
                <div
                  style={{
                    width: '100%',
                    height: '100%',
                    display: 'flex',
                    justifyContent: 'center',
                    alignItems: 'center',
                    marginLeft: 10,
                  }}
                >
                  {item.icon}
                </div>
              }
              title={
                _disabled ? (
                  <div style={{ color: 'rgba(0, 0, 0, 0.45)', marginLeft: 14 }}>{item.name}</div>
                ) : (
                  <div style={{ marginLeft: 14 }}>{item.name}</div>
                )
              }
            ></List.Item.Meta>
          </List.Item>
        );
      }}
    />
  );

  const onTabChange = (key: string) => {
    setCurrentTab(key);
  };

  const onUserSearchChang = (e: any) => {
    setUserGroupSearchValue(e.target.value);
  };

  return (
    <div className={`${PREFIX}-tab`}>
      <div className={`${PREFIX}-leftTree ${(ifUserGroupSelected && tab?.ifUserDepartmentSelected !== false) ? 'both' : ''}`}>
        {(ifUserGroupSelected && tab?.ifUserDepartmentSelected !== false) ? (
          <Tabs
            defaultActiveKey="department"
            centered={true}
            activeKey={currentTab}
            onChange={onTabChange}
          >
            <Tabs.TabPane
              tab={getMessage('MemberSelect.lang.personTabs.department')}
              key="department"
            >
              {departmentComponent}
            </Tabs.TabPane>
            <Tabs.TabPane
              tab={getMessage('MemberSelect.lang.personTabs.userGroup')}
              key="userGroup"
            >
              {userGroupComponent}
            </Tabs.TabPane>
          </Tabs>
        ) : tab?.ifUserDepartmentSelected !== false ? (
          departmentComponent
        ) : ifUserGroupSelected ? (
          userGroupComponent
        ) : (
          <Empty
            image={Empty.PRESENTED_IMAGE_SIMPLE}
            description={<TextWidget>MemberSelect.lang.noData</TextWidget>}
            style={{ marginTop: 168 }}
          />
        )}
      </div>
      <div className={`${PREFIX}-rightContent`}>
        {isGroup ? (
          <div style={{ padding: 10, borderBottom: '1px solid #eee' }}>
            <Input
              // 输入账号或姓名
              placeholder={getMessage(`MemberSelect.lang.enterAccountNumberOrName`)}
              style={{ width: 260 }}
              value={userGroupSearchValue}
              onChange={onUserSearchChang}
              suffix={
                <InbizIcon
                  type="icon-ic-sousuo"
                  style={{ fontSize: '15px', color: '#d9d9d9' }}
                  onClick={() => onUserGroupSearch()}
                />
              }
              onPressEnter={() => {
                onUserGroupSearch();
              }}
            />
          </div>
        ) : (
          <SearchBar
            // 包含子部门用户
            checkLabel={getMessage('MemberSelect.lang.includeSubDepartmentUsers')}
            // 输入账号或姓名
            placeholder={getMessage('MemberSelect.lang.enterAccountNumberOrName')}
            defaultChecked={isChild}
            defaultValue={departmentSearchValue}
            onSearch={onDepartmentSearch}
            onChange={_departmentSearchValue}
          />
        )}
        <DataTable
          rowSelection={{
            hideSelectAll: isUnique,
            getCheckboxProps: (r) => {
              return {
                disabled: forbiddenItems.includes(r.id),
              };
            },
          }}
          multiple={multiple}
          rowKey={rowKey}
          scroll={{
            scrollToFirstRowOnChange: true,
            y: calcTableScrollHeight(height, true),
          }}
          onRow={(item, index) => {
            return {
              onClick: (e) => {
                e.currentTarget
                  .querySelector(multiple ? '.ant-checkbox-wrapper' : '.ant-radio-wrapper')
                  ?.click();
                props.onRowClick?.(item, index);
              },
            };
          }}
          rowClassName={(r) => {
            if (forbiddenItems.includes(r.id)) {
              return 'datatable-forbidden-item';
            } else {
              return '';
            }
          }}
          pagination={
            isGroup
              ? {
                pageSize: groupPageSize,
                current: groupPageNum,
                total: groupTotal,
              }
              : {
                pageSize,
                current: pageNum,
                total,
              }
          }
          columns={[
            {
              width: 150,
              // 姓名(账号)
              title: <Text ellipsis={{ tooltip: true }}>{getMessage('MemberSelect.lang.nameAccountNumber')}</Text>,
              dataIndex: 'name',
              key: 'name',
              render: renderCellText(
                (record: any) =>
                  `${record.userloginname
                    ? record.name + '(' + record.userloginname + ')'
                    : record.name
                  }`,
                true,
              ),
            },
            {
              width: 175,
              // 部门
              title: <Text ellipsis={{ tooltip: true }}>{getMessage('MemberSelect.lang.personTabs.department')}</Text>,
              dataIndex: 'departmentname',
              key: 'departmentname',
              render: renderCellText('deptpathname', true),
            },
            {
              title: <Text ellipsis={{ tooltip: true }}>{getMessage('MemberSelect.lang.email')}</Text>,
              dataIndex: 'useremail',
              key: 'useremail',
              render: renderCellText('useremail', true),
            },
          ]}
          dataSource={isGroup ? userGroupUserList : departmentData}
          onChange={onPagination}
          selectedRowKeys={selectedRowKeys}
          onSelectChange={(keys, rows) => {
            setSelected(
              keys,
              isGroup ? userGroupUserList : departmentData,
              '',
              isGroup ? 'userGroup' : 'department',
            );
          }}
        />
      </div>
    </div>
  );
}
